package com.ruoyi.common.utils;

import cn.hutool.core.util.StrUtil;
import com.graphbuilder.math.Expression;
import com.graphbuilder.math.ExpressionTree;
import com.graphbuilder.math.FuncMap;
import com.graphbuilder.math.VarMap;
import com.ruoyi.common.core.text.Convert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.List;

import static java.lang.Integer.toHexString;

/**
 * 字节处理通用类
 */
public class ByteUtil {


    private static final Logger log = LoggerFactory.getLogger(ByteUtil.class);
    /** 遥控加扰多项式码表, 长度255, 加扰多项式, 101011111, 5f */
    public static int jrArray5F[] = {
            0xFF,0x39,0x9E,0x5A,0x68,0xE9,0x06,0xF5,0x6C,0x89,
            0x2F,0xA1,0x31,0x5E,0x08,0xC0,0x52,0xA8,0xBB,0xAE,
            0x4E,0xC2,0xC7,0xED,0x66,0xDC,0x38,0xD4,0xF8,0x86,
            0x50,0x3D,0xFE,0x73,0x3C,0xB4,0xD1,0xD2,0x0D,0xEA,
            0xD9,0x12,0x5F,0x42,0x62,0xBC,0x11,0x80,0xA5,0x51,
            0x77,0x5C,0x9D,0x85,0x8F,0xDA,0xCD,0xB8,0x71,0xA9,
            0xF1,0x0C,0xA0,0x7B,0xFC,0xE6,0x79,0x69,0xA3,0xA4,
            0x1B,0xD5,0xB2,0x24,0xBE,0x84,0xC5,0x78,0x23,0x01,
            0x4A,0xA2,0xEE,0xB9,0x3B,0x0B,0x1F,0xB5,0x9B,0x70,
            0xE3,0x53,0xE2,0x19,0x40,0xF7,0xF9,0xCC,0xF2,0xD3,
            0x47,0x48,0x37,0xAB,0x64,0x49,0x7D,0x09,0x8A,0xF0,
            0x46,0x02,0x95,0x45,0xDD,0x72,0x76,0x16,0x3F,0x6B,
            0x36,0xE1,0xC6,0xA7,0xC4,0x32,0x81,0xEF,0xF3,0x99,
            0xE5,0xA6,0x8E,0x90,0x6F,0x56,0xC8,0x92,0xFA,0x13,
            0x15,0xE0,0x8C,0x05,0x2A,0x8B,0xBA,0xE4,0xEC,0x2C,
            0x7E,0xD6,0x6D,0xC3,0x8D,0x4F,0x88,0x65,0x03,0xDF,
            0xE7,0x33,0xCB,0x4D,0x1D,0x20,0xDE,0xAD,0x91,0x25,
            0xF4,0x26,0x2B,0xC1,0x18,0x0A,0x55,0x17,0x75,0xC9,
            0xD8,0x58,0xFD,0xAC,0xDB,0x87,0x1A,0x9F,0x10,0xCA,
            0x07,0xBF,0xCE,0x67,0x96,0x9A,0x3A,0x41,0xBD,0x5B,
            0x22,0x4B,0xE8,0x4C,0x57,0x82,0x30,0x14,0xAA,0x2E,
            0xEB,0x93,0xB0,0xB1,0xFB,0x59,0xB7,0x0E,0x35,0x3E,
            0x21,0x94,0x0F,0x7F,0x9C,0xCF,0x2D,0x34,0x74,0x83,
            0x7A,0xB6,0x44,0x97,0xD0,0x98,0xAF,0x04,0x60,0x29,
            0x54,0x5D,0xD7,0x27,0x61,0x63,0xF6,0xB3,0x6E,0x1C,
            0x6A,0x7C,0x43,0x28,0x1E};

    /** 遥测加扰多项式码表, 长度255, 加扰多项式, 110101001, a9 */
    public static int jrArrayA9[] = {
            0xFF,0x48,0x0E,0xC0,0x9A,0x0D,0x70,0xBC,0x8E,0x2C,
            0x93,0xAD,0xA7,0xB7,0x46,0xCE,0x5A,0x97,0x7D,0xCC,
            0x32,0xA2,0xBF,0x3E,0x0A,0x10,0xF1,0x88,0x94,0xCD,
            0xEA,0xB1,0xFE,0x90,0x1D,0x81,0x34,0x1A,0xE1,0x79,
            0x1C,0x59,0x27,0x5B,0x4F,0x6E,0x8D,0x9C,0xB5,0x2E,
            0xFB,0x98,0x65,0x45,0x7E,0x7C,0x14,0x21,0xE3,0x11,
            0x29,0x9B,0xD5,0x63,0xFD,0x20,0x3B,0x02,0x68,0x35,
            0xC2,0xF2,0x38,0xB2,0x4E,0xB6,0x9E,0xDD,0x1B,0x39,
            0x6A,0x5D,0xF7,0x30,0xCA,0x8A,0xFC,0xF8,0x28,0x43,
            0xC6,0x22,0x53,0x37,0xAA,0xC7,0xFA,0x40,0x76,0x04,
            0xD0,0x6B,0x85,0xE4,0x71,0x64,0x9D,0x6D,0x3D,0xBA,
            0x36,0x72,0xD4,0xBB,0xEE,0x61,0x95,0x15,0xF9,0xF0,
            0x50,0x87,0x8C,0x44,0xA6,0x6F,0x55,0x8F,0xF4,0x80,
            0xEC,0x09,0xA0,0xD7,0x0B,0xC8,0xE2,0xC9,0x3A,0xDA,
            0x7B,0x74,0x6C,0xE5,0xA9,0x77,0xDC,0xC3,0x2A,0x2B,
            0xF3,0xE0,0xA1,0x0F,0x18,0x89,0x4C,0xDE,0xAB,0x1F,
            0xE9,0x01,0xD8,0x13,0x41,0xAE,0x17,0x91,0xC5,0x92,
            0x75,0xB4,0xF6,0xE8,0xD9,0xCB,0x52,0xEF,0xB9,0x86,
            0x54,0x57,0xE7,0xC1,0x42,0x1E,0x31,0x12,0x99,0xBD,
            0x56,0x3F,0xD2,0x03,0xB0,0x26,0x83,0x5C,0x2F,0x23,
            0x8B,0x24,0xEB,0x69,0xED,0xD1,0xB3,0x96,0xA5,0xDF,
            0x73,0x0C,0xA8,0xAF,0xCF,0x82,0x84,0x3C,0x62,0x25,
            0x33,0x7A,0xAC,0x7F,0xA4,0x07,0x60,0x4D,0x06,0xB8,
            0x5E,0x47,0x16,0x49,0xD6,0xD3,0xDB,0xA3,0x67,0x2D,
            0x4B,0xBE,0xE6,0x19,0x51,0x5F,0x9F,0x05,0x08,0x78,
            0xC4,0x4A,0x66,0xF5,0x58};


    private static String[] binaryArray =
            {"0000", "0001", "0010", "0011",
                    "0100", "0101", "0110", "0111",
                    "1000", "1001", "1010", "1011",
                    "1100", "1101", "1110", "1111"};

    //构造一个8*8的二维数据， 第一个为字节数，第二个为左移数
    private static long[][] s = new long[8][8];

    static {
        long[] s1 = {0xffl, 0xffffl, 0xffffffl, 0xffffffffl, 0xffffffffffl, 0xffffffffffffl, 0xffffffffffffffl, 0xffffffffffffffffl};
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                s[i][j] = (((0xff << (i * 8)) | s1[i]) >>> j);
            }
        }
    }

    /**
     * 16进制数据转换byte数组
     *
     * @param hexString 16进制数据
     * @return byte数组
     */
    public final static byte[] hexToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) ((byte) "0123456789ABCDEF".indexOf(hexChars[pos]) << 4 | (byte) "0123456789ABCDEF"
                    .indexOf(hexChars[pos + 1]));
        }
        return d;
    }


    /**
     * 16进制数据转换byte数组。16进制数据长度为奇数时补零
     *
     * @param hexString 16进制数据
     * @return 补零后的byte数组
     */
    public final static byte[] hexToBytesZeroFill(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        if (hexString.length() % 2 !=0 ) {
            hexString = "0"+hexString;
        }

        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) ((byte) "0123456789ABCDEF".indexOf(hexChars[pos]) << 4 | (byte) "0123456789ABCDEF"
                    .indexOf(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * byte数组转换为16进制数据
     *
     * @param src byte数组
     * @return 转换后的16进制数据
     */
    public final static String bytesToHex(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * byte转16进制
     *
     * @param src
     * @return
     */
    public final static String byteToHex(byte src) {
        String hv = toHexString(src & 0xFF);
        if (hv.length() < 2) {
            hv = "0" + hv;
        }
        return hv;
    }

    /**
     * 16进制转byte
     *
     * @param hex
     * @return
     */
    public final static byte hexToByte(String hex) {
        char[] hexChars = hex.toCharArray();
        return (byte) ((byte) "0123456789ABCDEF".indexOf(hexChars[0]) << 4 | (byte) "0123456789ABCDEF".indexOf(hexChars[1]));
    }

    /**
     * <pre>
     * 将4个byte数字组成的数组合并为一个float数.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static float byte4ToFloat(byte[] arr) {
        if (arr == null || arr.length != 4) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是4位!");
        }
        int i = byte4ToInt(arr);
        return Float.intBitsToFloat(i);
    }

    /**
     * <pre>
     * 将一个float数字转换为4个byte数字组成的数组.
     * </pre>
     *
     * @param f
     * @return
     */
    public static byte[] floatToByte4(float f) {
        int i = Float.floatToIntBits(f);
        return intToByte4(i);
    }

    /**
     * <pre>
     * 将八个byte数字组成的数组转换为一个double数字.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static double byte8ToDouble(byte[] arr) {
        if (arr == null || arr.length != 8) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是8位!");
        }
        long l = byte8ToLong(arr);
        return Double.longBitsToDouble(l);
    }

    /**
     * <pre>
     * 将一个double数字转换为8个byte数字组成的数组.
     * </pre>
     *
     * @param i
     * @return
     */
    public static byte[] doubleToByte8(double i) {
        long j = Double.doubleToLongBits(i);
        return longToByte8(j);
    }

    /**
     * 16进制数据转换为单精度浮点数
     *
     * @param hexString 16进制数据
     * @return 转换后的单精度浮点数
     */
    public final static float hexToFloat(String hexString) {
        return Float.intBitsToFloat((int) Long.parseLong(hexString, 16));
    }

    /**
     * 单精度浮点数转换为16进制数据
     *
     * @param f 单精度浮点数
     * @return 转换后的16进制数据
     */
    public final static String floatToHex(float f) {
        if (f == 0) return "00000000";
        return toHexString(Float.floatToIntBits(f));
    }

    /**
     * 16进制数据转换为双精度浮点数
     *
     * @param hexString 16进制数据
     * @return 转换后的双精度浮点数
     */
    public final static double hexToDouble(String hexString) {
        BigInteger bi = new BigInteger(hexString, 16);
        return Double.longBitsToDouble(bi.longValue());
    }

    /**
     * 双精度浮点数转换为16进制数据
     *
     * @param d 双精度浮点数
     * @return 转换后的16进制数据
     */
    public final static String doubleToHex(double d) {
        return Long.toHexString(Double.doubleToLongBits(d));
    }

    /**
     * <pre>
     * 将一个char字符转换为两个byte数字转换为的数组.
     * </pre>
     *
     * @param c
     * @return
     */
    public static byte[] charToByte2(char c) {
        byte[] arr = new byte[2];
        arr[0] = (byte) (c >> 8);
        arr[1] = (byte) (c & 0xff);
        return arr;
    }

    /**
     * <pre>
     * 将2个byte数字组成的数组转换为一个char字符.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static char byte2ToChar(byte[] arr) {
        if (arr == null || arr.length != 2) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是2位!");
        }
        return (char) (((char) (arr[0] << 8)) | ((char) arr[1]));
    }

    /**
     * <pre>
     * 将一个16位的short转换为长度为2的8位byte数组.
     * </pre>
     *
     * @param s
     * @return
     */
    public static byte[] shortToByte2(Short s) {
        byte[] arr = new byte[2];
        arr[0] = (byte) (s >> 8);
        arr[1] = (byte) (s & 0xff);
        return arr;
    }

    /**
     * <pre>
     * 长度为2的8位byte数组转换为一个16位short数字.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static short byte2ToShort(byte[] arr) {
        if (arr != null && arr.length != 2) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是2位!");
        }
        return (short) (((short) arr[0] << 8) | ((short) arr[1] & 0xff));
    }

    /**
     * <pre>
     * 将short转换为长度为16的byte数组.
     * 实际上每个8位byte只存储了一个0或1的数字
     * 比较浪费.
     * </pre>
     *
     * @param s
     * @return
     */
    public static byte[] shortToByte16(short s) {
        byte[] arr = new byte[16];
        for (int i = 15; i >= 0; i--) {
            arr[i] = (byte) (s & 1);
            s >>= 1;
        }
        return arr;
    }

    /**
     * 将byte数组转换为short.
     *
     * @param arr
     * @return
     */
    public static short byte16ToShort(byte[] arr) {
        if (arr == null || arr.length != 16) {
            throw new IllegalArgumentException("byte数组必须不为空,并且长度为16!");
        }
        short sum = 0;
        for (int i = 0; i < 16; ++i) {
            sum |= (arr[i] << (15 - i));
        }
        return sum;
    }

    /**
     * <pre>
     * 将32位int转换为由四个8位byte数字.
     * </pre>
     *
     * @param sum
     * @return
     */
    public static byte[] intToByte4(int sum) {
        byte[] arr = new byte[4];
        arr[0] = (byte) (sum >> 24);
        arr[1] = (byte) (sum >> 16);
        arr[2] = (byte) (sum >> 8);
        arr[3] = (byte) (sum & 0xff);
        return arr;
    }

    /**
     * <pre>
     * 将长度为4的8位byte数组转换为32位int.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static int byte4ToInt(byte[] arr) {
        if (arr == null || arr.length != 4) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是4位!");
        }
        return (int) (((arr[0] & 0xff) << 24) | ((arr[1] & 0xff) << 16) | ((arr[2] & 0xff) << 8) | ((arr[3] & 0xff)));
    }

    /**
     * <pre>
     * 将长度为8的8位byte数组转换为64位long.
     * </pre>
     * <p>
     * 0xff对应16进制,f代表1111,0xff刚好是8位 byte[]
     * arr,byte[i]&0xff刚好满足一位byte计算,不会导致数据丢失. 如果是int计算. int[] arr,arr[i]&0xffff
     *
     * @param arr
     * @return
     */
    public static long byte8ToLong(byte[] arr) {
        if (arr == null || arr.length != 8) {
            throw new IllegalArgumentException("byte数组必须不为空,并且是8位!");
        }
        return (long) (((long) (arr[0] & 0xff) << 56) | ((long) (arr[1] & 0xff) << 48) | ((long) (arr[2] & 0xff) << 40)
                | ((long) (arr[3] & 0xff) << 32) | ((long) (arr[4] & 0xff) << 24)
                | ((long) (arr[5] & 0xff) << 16) | ((long) (arr[6] & 0xff) << 8) | ((long) (arr[7] & 0xff)));
    }

    /**
     * 将一个long数字转换为8个byte数组组成的数组.
     */
    public static byte[] longToByte8(long sum) {
        byte[] arr = new byte[8];
        arr[0] = (byte) (sum >> 56);
        arr[1] = (byte) (sum >> 48);
        arr[2] = (byte) (sum >> 40);
        arr[3] = (byte) (sum >> 32);
        arr[4] = (byte) (sum >> 24);
        arr[5] = (byte) (sum >> 16);
        arr[6] = (byte) (sum >> 8);
        arr[7] = (byte) (sum & 0xff);
        return arr;
    }

    /**
     * long转字节数组
     *
     * @param n
     * @param len
     * @return
     */
    public static byte[] longToBytes(long n, int len) {
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (n >> ((len - i - 1) * 8) & 0xff);
        }
        return b;
    }

    /**
     * <pre>
     * 将int转换为32位byte.
     * 实际上每个8位byte只存储了一个0或1的数字
     * 比较浪费.
     * </pre>
     *
     * @param num
     * @return
     */
    public static byte[] intToByte32(int num) {
        byte[] arr = new byte[32];
        for (int i = 31; i >= 0; i--) {
            // &1 也可以改为num&0x01,表示取最地位数字.
            arr[i] = (byte) (num & 1);
            // 右移一位.
            num >>= 1;
        }
        return arr;
    }

    /**
     * <pre>
     * 将长度为32的byte数组转换为一个int类型值.
     * 每一个8位byte都只存储了0或1的数字.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static int byte32ToInt(byte[] arr) {
        if (arr == null || arr.length != 32) {
            throw new IllegalArgumentException("byte数组必须不为空,并且长度是32!");
        }
        int sum = 0;
        for (int i = 0; i < 32; ++i) {
            sum |= (arr[i] << (31 - i));
        }
        return sum;
    }

    /**
     * <pre>
     * 将长度为64的byte数组转换为一个long类型值.
     * 每一个8位byte都只存储了0或1的数字.
     * </pre>
     *
     * @param arr
     * @return
     */
    public static long byte64ToLong(byte[] arr) {
        if (arr == null || arr.length != 64) {
            throw new IllegalArgumentException("byte数组必须不为空,并且长度是64!");
        }
        long sum = 0L;
        for (int i = 0; i < 64; ++i) {
            sum |= ((long) arr[i] << (63 - i));
        }
        return sum;
    }

    /**
     * <pre>
     * 将一个long值转换为长度为64的8位byte数组.
     * 每一个8位byte都只存储了0或1的数字.
     * </pre>
     *
     * @param sum
     * @return
     */
    public static byte[] longToByte64(long sum) {
        byte[] arr = new byte[64];
        for (int i = 63; i >= 0; i--) {
            arr[i] = (byte) (sum & 1);
            sum >>= 1;
        }
        return arr;
    }

    /**
     * 2 byte[] 转 int
     *
     * @param bytes
     * @return
     */
    public static int byte2ToInt(byte[] bytes) {
        int value = 0;
        // 由高位到低位
        for (int i = 0; i < 2; i++) {
            int shift = (2 - 1 - i) * 8;
            value += (bytes[i] & 0x00FF) << shift;// 往高位游
        }
        return value;
    }

    /**
     * bytes数组转int
     *
     * @param bytes
     * @return
     */
    public static int bytesToInt(byte[] bytes) {
        int value = 0;
        // 由高位到低位
        for (int i = 0; i < bytes.length; i++) {
            int shift = (bytes.length - 1 - i) * 8;
            value += (bytes[i] & 0x000000FF) << shift;// 往高位游
        }
        return value;
    }

    public static int byteToInt(byte b) {
        return b & 0x000000FF;
    }


    /**
     * 十进制转byte数组
     *
     * @param n
     * @param len
     * @return
     */
    public static byte[] intToBytes(int n, int len) {
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (n >> ((len - i - 1) * 8) & 0xff);
        }
        return b;
    }

    /**
     * int 转 byte
     *
     * @param n
     * @return
     */
    public static byte intToByte(int n) {
        return (byte) n;
    }

    /**
     * byte转二进制字符串
     *
     * @param by
     * @return
     */
    public static String byteToBit(byte by) {
        return Integer.toBinaryString((by & 0xFF) + 0x100).substring(1);
    }

    /**
     * byte数组转二进制字符串
     *
     * @param by
     * @return
     */
    public static String bytesToBit(byte by[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < by.length; i++) {
            sb.append(Integer.toBinaryString((by[i] & 0xFF) + 0x100).substring(1));
        }
        return sb.toString();
    }

    /**
     * 10进制转2进制
     *
     * @param num    10进制值
     * @param digits 从低位开始取二进制值数量
     * @return
     */
    public static String decToBinary(int num, int digits) {
        String cover = Integer.toBinaryString(1 << digits).substring(1);
        String s = Integer.toBinaryString(num);
        return s.length() < digits ? cover.substring(s.length()) + s : s;
    }

    public static String longToBinary(long number, int digits) {
        StringBuilder binary = new StringBuilder();
        for (int i = digits - 1; i >= 0; i--) {
            long mask = 1L << i;
            binary.append((number & mask) != 0 ? '1' : '0');
        }
        return binary.toString();
    }

    /**
     * 10进制转2进制
     *
     * @param num 10进制值
     * @return 8位二进制字符串
     */
    public static String decToBinary(int num) {
        return decToBinary(num, 8);
    }

    /**
     * 10进制转2进制不补0
     *
     * @param num
     * @return
     */
    public static String decToBinaryn(int num) {
        return Integer.toBinaryString(num & 0xFF);
    }

    public static String decimalToBinary(int decimal, int len) {
        if (decimal == 0) {
            return FullBinary("0", len);
        }

        StringBuilder binary = new StringBuilder();
        while (decimal > 0) {
            int remainder = decimal % 2;
            binary.insert(0, remainder);
            decimal = decimal / 2;
        }

        return FullBinary(binary.toString(), len);
    }

    /**
     * 二进制转10进制
     *
     * @param binary
     * @return
     */
    public static int binaryToDec(String binary) {
        return Integer.parseInt(binary, 2);
    }

    public static long binaryToLong(String binary) {
        return Long.parseLong(binary, 2);
    }

    /**
     * 二进制转byte数组
     *
     * @param binary
     * @return
     */
    public static byte[] binaryToBytes(String binary) {
        int length = binary.length() / 8;
        byte[] b = new byte[length];
        for (int i = 0; i < b.length; i++) {
            b[i] = Long.valueOf(binary.substring(i * 8, (i + 1) * 8), 2).byteValue();
        }
        return b;
    }

    /**
     * 二进制转byte
     *
     * @param binary
     * @return
     */
    public static byte binaryToByte(String binary) {
        return Long.valueOf(binary, 2).byteValue();
    }

    /**
     * 截取取字节数组
     *
     * @param bytes    字节数组
     * @param bytePos0 起始字节位置0开始
     * @param byteLen  字节长度
     * @return 字节数组
     */
    public static byte[] subBytes(byte[] bytes, int bytePos0, Integer byteLen) {
        if (byteLen == null){
            return subBytes(bytes, bytePos0);
        }
        if (bytes == null || byteLen == 0 || bytes.length < bytePos0 + byteLen) {
            return null;
        }
        byte[] b = new byte[byteLen];
        System.arraycopy(bytes, bytePos0, b, 0, byteLen);
        return b;
    }

    /**
     * 截取字节数组
     *
     * @param bytes    字节数组
     * @param bytePos0 起始字节位置
     * @return
     */
    public static byte[] subBytes(byte[] bytes, int bytePos0) {
        if (bytePos0 == 0) return bytes;
        if (bytes == null || bytes.length <= bytePos0) return null;
        int byteLen = bytes.length - bytePos0;
        byte[] b = new byte[byteLen];
        System.arraycopy(bytes, bytePos0, b, 0, byteLen);
        return b;
    }

    /**
     * 检验和
     *
     * @param b
     * @return
     */
    public static byte sumCheckf(byte[] b) {
        if (b == null) return 0x00;
        int sum = 0;
        for (int i = 0; i < b.length; i++) {
            sum = sum + b[i];
        }
        if (sum > 0xff) { //超过了255，使用补码（补码 = 原码取反 + 1）
            sum = ~sum;
            sum = sum + 1;
        }
        return (byte) (sum & 0xff);
    }

    /**
     * 检验和 无符号
     *
     * @param b
     * @return
     */
    public static byte sumCheck(byte[] b) {
        if (b == null) return 0x00;
        int sum = 0;
        for (int i = 0; i < b.length; i++) {
            sum = sum + (b[i] & 0x000000FF) << 0;
        }
        if (sum > 0xff) {
            sum = sum % 0x100;
        }
        return (byte) (sum & 0xff);
    }

    /**
     * 检验和2字节 无符号
     *
     * @param b
     * @return
     */
    public static byte[] sumCheck2(byte[] b) {
        if (b == null) return new byte[]{0x00, 0x00};
        int sum = 0;
        for (int i = 0; i < b.length; i++) {
            sum += byteToInt(b[i]);
        }
        if (sum > 0x10000){
            sum = sum % 0x10000;
        }
        return ByteUtil.intToBytes(sum, 2);
    }

    /**
     * 校验和整型 取反
     * @param b
     * @return
     */
    public static int sumCheck4(byte[] b) {
        if (b == null) return 0;
        Long sum = 0L;
        for (int i = 0; i < b.length; i++) {
            sum += (byte) b[i];
        }
        if (sum > Integer.MAX_VALUE) {
            sum = sum % Integer.MAX_VALUE;
        }

        return ~sum.intValue();
    }

    public static int sumCheckInt(byte[] b) {
        if (b == null) return 0;
        int sum = 0;
        for (int i = 0; i < b.length / 4; i++) {
            sum += bytesToIntf(subBytes(b, i * 4, 4));
        }
        return ~sum + 1;
    }

    public static byte sumXorCheck(byte[] b){
        if(b == null) return 0x00;
        int sum = 0;
        for(int i = 0; i < b.length; i++){
            sum ^= b[i];
        }
        return (byte) (sum & 0xff);
    }

    public static byte[] sumXorCheck2(byte[] b){
        int sum = sumCheck4(b);
        return ByteUtil.intToBytes(sum, 2);
    }

    /**
     * 10进制转16进制
     *
     * @param v 10进制数据
     * @return 转换后的16进制数据
     */
    public final static String decToHex(int v) {
        String rtn_hex = Long.toHexString(v);
        if (rtn_hex.length() % 2 != 0) {
            rtn_hex = "0" + rtn_hex;
        }
        return rtn_hex;
    }

    /**
     * 十进制转十六进制
     *
     * @param i   值
     * @param len 字节长度
     * @return
     */
    public final static String decToHex(int i, int len) {
        String rtn_hex = Long.toHexString(i);
        if (rtn_hex.length() % 2 != 0) {
            rtn_hex = "0" + rtn_hex;
        }
        while (rtn_hex.length() < len * 2) {
            rtn_hex = "0" + rtn_hex;
        }
        if (rtn_hex.length() > len * 2){
            rtn_hex = rtn_hex.substring(rtn_hex.length() - len * 2);
        }
        return rtn_hex;
    }

    /**
     * 16进制转10进制
     *
     * @param hex 16进制数据
     * @return 转换后的10进制数据
     */
    public final static int hexToDec(String hex) {
        if (hex == null || hex.equals("")) {
            return 0;
        }
        return Integer.valueOf(hex, 16);
    }

    public final static long hexToLong(String hex) {
        if (StringUtils.isEmpty(hex)) {
            return 0;
        }
        return Long.valueOf(hex, 16);
    }

    /**
     * 字节数组搜索， 返回开始位的索引
     *
     * @param src   源数组
     * @param bytes 目标数组
     * @return
     */
    public static int byteIndexOf(byte[] src, byte[] bytes) {
        return byteIndexOf(src, bytes, 0);
    }

    /**
     * 字节数组搜索，指定开始位置
     *
     * @param src
     * @param bytes
     * @param bi
     * @return
     */
    public static int byteIndexOf(byte[] src, byte[] bytes, int bi) {
        if (bytes == null || src == null) return -1;
        for (int i = bi; i < bytes.length - src.length + 1; i++) {
            boolean tmp = true;
            for (int j = 0; j < src.length; j++) {
                if (src[j] != bytes[j + i]) {
                    tmp = false;
                }
            }
            if (tmp) return i;
        }
        return -1;
    }

    /**
     * 字节数组搜索， 返回开始位的索引  从后往前找
     *
     * @param src   源数组
     * @param bytes 目标数组
     * @return
     */
    public static int byteLastIndexOf(byte[] src, byte[] bytes) {
        if (bytes == null || src == null) return -1;
        for (int i = bytes.length - src.length; i >= 0; i--) {
            boolean tmp = true;
            for (int j = 0; j < src.length; j++) {
                if (src[j] != bytes[j + i]) {
                    tmp = false;
                }
            }
            if (tmp) return i;
        }
        return -1;
    }

    /**
     * 字节数据拼接
     *
     * @param bt1
     * @param bt2
     * @return
     */
    public static byte[] byteMerger(byte[] bt1, byte[] bt2) {
        if (bt1 == null) return bt2;
        if (bt2 == null) return bt1;
        byte[] bt3 = new byte[bt1.length + bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    /**
     * 字节数据拼接
     *
     * @param values
     * @return
     */
    public static byte[] byteMergerAll(byte[]... values) {
        int length_byte = 0;
        for (int i = 0; i < values.length; i++) {
            length_byte += values[i].length;
        }
        byte[] all_byte = new byte[length_byte];
        int countLength = 0;
        for (int i = 0; i < values.length; i++) {
            byte[] b = values[i];
            System.arraycopy(b, 0, all_byte, countLength, b.length);
            countLength += b.length;
        }
        return all_byte;
    }


    /**
     * double格式化小数位
     *
     * @param d   double
     * @param bit bit位小数
     * @return
     */
    public static String doubleFormat(double d, int bit) {
        return String.format("%." + bit + "f", d);
    }

    /**
     * 数据转义处理
     *
     * @param source 源码
     * @param bytes  需要转义的标识， 如果遇到此数据数组则判断前面字节是否为0 如果为0则删除此字节
     * @return
     */
    public static byte[] byteParaphrase(byte[] source, List<byte[]> bytes) {
        // TODO   do something

        return source;
    }

    /**
     * 16进制转十进制 有符号
     *
     * @param hex
     * @return
     */
    public static int hexToIntf(String hex) {
        int ret = new BigInteger(hex, 16).intValue();
        if (hex.length() == 2) {
            ret = ((ret & 0xff) > 0) ? (ret - 0x100) : (ret);
        } else if (hex.length() == 4) {
            ret = ((ret & 0xffff) > 0) ? (ret - 0x10000) : (ret);
        } else if (hex.length() == 6) {
            ret = ((ret & 0xffffff) > 0) ? (ret - 0x1000000) : (ret);
        }
        return ret;
    }

    /**
     * 字节数组转int 有符号
     *
     * @param bytes
     * @return
     */
    public static int bytesToIntf(byte[] bytes) {
        int ret = bytesToInt(bytes);
        if (bytes.length == 1) {
            ret = ((ret & 0xff) > 0) ? (ret - 0x100) : (ret);
        } else if (bytes.length == 2) {
            ret = ((ret & 0xffff) > 0) ? (ret - 0x10000) : (ret);
        } else if (bytes.length == 3) {
            ret = ((ret & 0xffffff) > 0) ? (ret - 0x1000000) : (ret);
        }
        return ret;
    }

    /**
     * 字节数组转long 有符号
     *
     * @param bytes
     * @return
     */
    public static long bytesToLongf(byte[] bytes) {
        long ret = bytesToLong(bytes);
        if (bytes.length == 1) {
            ret = ((ret & 0xff) > 0) ? (ret - 0x100) : (ret);
        } else if (bytes.length == 2) {
            ret = ((ret & 0xffff) > 0) ? (ret - 0x10000) : (ret);
        } else if (bytes.length == 3) {
            ret = ((ret & 0xffffff) > 0) ? (ret - 0x1000000) : (ret);
        } else if (bytes.length == 4) {
            ret = ((ret & 0xffffffffl) > 0) ? (ret - 0x100000000l) : (ret);
        } else if (bytes.length == 5) {
            ret = ((ret & 0xffffffffffl) > 0) ? (ret - 0x10000000000l) : (ret);
        } else if (bytes.length == 6) {
            ret = ((ret & 0xffffffffffffl) > 0) ? (ret - 0x1000000000000l) : (ret);
        } else if (bytes.length == 7) {
            ret = ((ret & 0xffffffffffffffl) > 0) ? (ret - 0x100000000000000l) : (ret);
        }
        return ret;
    }

    public static long bytesToLongf1(byte[] bytes) {
        long ret = bytesToLong(bytes);
        if (bytes.length == 1) {
            ret = ((ret & 0x80) > 0) ? (ret - 0x100) : (ret);
        } else if (bytes.length == 2) {
            ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
        } else if (bytes.length == 3) {
            ret = ((ret & 0x800000) > 0) ? (ret - 0x1000000) : (ret);
        } else if (bytes.length == 4) {
            ret = ((ret & 0x80000000) > 0) ? (ret - 0x100000000l) : (ret);
        } else if (bytes.length == 5) {
            ret = ((ret & 0x8000000000L) > 0) ? (ret - 0x10000000000l) : (ret);
        } else if (bytes.length == 6) {
            ret = ((ret & 0x800000000000L) > 0) ? (ret - 0x1000000000000l) : (ret);
        } else if (bytes.length == 7) {
            ret = ((ret & 0x80000000000000L) > 0) ? (ret - 0x100000000000000l) : (ret);
        }
        return ret;
    }

    /**
     * 反码处理
     * @param bytes
     * @param symbol 符号位是否反码 false 有符号   true 无符号
     * @return
     */
    public static long bytesInverseCode(byte[] bytes, boolean symbol){
        byte[] invertedArray = new byte[bytes.length];

        for (int i = 0; i < bytes.length; i++) {
            if (i == 0){
                if (!symbol){
                    // 获取符号位的值
                    int sv = (bytes[i] & 0x80) >> 7;
                    if (sv == 0){
                        invertedArray[i] = (byte) (((byte) ~bytes[i]) & 0x7f);
                    }else {
                        invertedArray[i] = (byte) (((byte) ~bytes[i]) | 0x80);
                    }
                }else {
                    invertedArray[i] = (byte) ~bytes[i];
                }
            }else {
                invertedArray[i] = (byte) ~bytes[i];
            }
        }
        return ByteUtil.bytesToLong(invertedArray);
    }

    /**
     * 按位取出需要的字节
     *
     * @return
     */
    public static byte[] bytesBeginLen(byte[] bytes, int start_bit, int bit_len) {
        int start_byte = start_bit / Byte.SIZE;
        int end_byte = (start_bit + bit_len) % Byte.SIZE == 0 ? (start_bit + bit_len) / Byte.SIZE : (start_bit + bit_len) / Byte.SIZE + 1;
        return subBytes(bytes, start_byte, end_byte - start_byte);
    }

    /**
     * bytes 转long
     *
     * @param bytes
     * @return
     */
    public static Long bytesToLong(byte[] bytes) {
        long l = 0L;
        for (int i = 0; i < bytes.length; i++) {
            l |= (bytes[i] & 0xffL) << (((bytes.length - 1) - i) * 8);
        }
        return l;
    }

    /**
     * 获取字节数组指定位的值
     *
     * @param data      所用到的字节
     * @param start_bit 开始位
     * @param bit_len   取位长度
     * @return
     */
    public static Long bytesToLong(byte[] data, int start_bit, int bit_len) {
        //需要左移的个数
        int left_num = (start_bit % 8);
        //需要右移的个数
        int right_num = data.length * 8 - bit_len - left_num;
        //字节转换为long
        long l = bytesToLong(data);
        // 主要操作！！  将前面的1&掉， 再向右移则取到了截取后的值
        return (l & s[data.length - 1][left_num]) >>> right_num;
    }

    public static Long bytesToLong2(byte[] data, int start_bit, int bit_len){
        byte[] bytes = bytesBeginLen(data, start_bit, bit_len);
        return bytesToLong(bytes, start_bit, bit_len);
    }

    /**
     * 3个字节低7位计算整型
     *
     * @param data
     * @return
     */
    public static int bytes3ToIntLow7(byte[] data) {
        StringBuffer binary = bytesToBinary(data);
        binary.deleteCharAt(0).deleteCharAt(7).deleteCharAt(14);
        return binaryToDec(binary.toString());
    }

    /**
     * 2个字节低7位计算整型
     *
     * @param data
     * @return
     */
    public static int bytes2ToIntLow7(byte[] data) {
        byte b2 = (byte) ((data[0] << 7));
        byte b3 = (byte) (data[1] & 0x7F);  //两个都是1则为1 否则就为0
        byte di8 = (byte) (b2 | b3);   //两个数只要有一个为1则为1，否则就为0
        byte gao6 = (byte) ((data[0] >> 1) & 0x3f);
        byte[] x = {gao6, di8};
        return ByteUtil.bytesToInt(x);
    }

    /**
     * 3个字节低277位计算整型
     *
     * @param data
     * @return
     */
    public static int bytes3ToIntLow277(byte[] data) {
        byte b2 = (byte) ((data[1] << 7));
        byte b3 = (byte) (data[2] & 0x7F);  //两个都是1则为1 否则就为0
        byte di8 = (byte) (b2 | b3);   //两个数只要有一个为1则为1，否则就为0
        byte gao6 = (byte) ((data[1] >> 1) & 0x3f);
        byte gao2 = (byte) ((data[0] & 0x03) << 6);
        byte[] x = {(byte) (gao2 | gao6), di8};
        return ByteUtil.bytesToInt(x);
    }


    /**
     * 两个字节低6位计算整型
     *
     * @param data
     * @return
     */
    public static int bytes2ToIntLow6(byte[] data) {
        byte b2 = (byte) ((data[0] << 6));
        byte b3 = (byte) (data[1] & 0x3F);  //两个都是1则为1 否则就为0
        byte di8 = (byte) (b2 | b3);   //两个数只要有一个为1则为1，否则就为0
        byte gao4 = (byte) ((data[0] >> 2) & 0x0f);
        byte[] x = {gao4, di8};
        return ByteUtil.bytesToInt(x);
    }

    /**
     * 两个字节低5位计算整型
     *
     * @param data
     * @return
     */
    public static int bytes2ToIntLow5(byte[] data) {
        byte b2 = (byte) ((data[0] << 5));
        byte b3 = (byte) (data[1] & 0x1F);  //两个都是1则为1 否则就为0
        byte di8 = (byte) (b2 | b3);   //两个数只要有一个为1则为1，否则就为0
        byte gao2 = (byte) ((data[0] >> 3) & 0x03);
        byte[] x = {gao2, di8};
        return ByteUtil.bytesToInt(x);
    }

    /**
     * @param bArray
     * @return 转换为二进制字符串
     */
    public static StringBuffer bytesToBinary(byte[] bArray) {
        StringBuffer outStr = new StringBuffer();
        int pos = 0;
        for (byte b : bArray) {
            //高四位
            pos = (b & 0xF0) >> 4;
            outStr.append(binaryArray[pos]);
            //低四位
            pos = b & 0x0F;
            outStr.append(binaryArray[pos]);
        }
        return outStr;
    }

    /**
     * 字节数组转二进制字符串，并控制输出长度
     * @param bytes 字节数组
     * @param len 目标二进制字符串长度
     * @return 二进制字符串
     */
    public static String bytesToBinary(byte[] bytes, int len) {
        StringBuilder binaryStr = new StringBuilder();
        for (byte b : bytes) {
            binaryStr.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
        }
        // 如果超过长度，截取后len位
        if (binaryStr.length() > len) {
            return binaryStr.substring(binaryStr.length() - len);
        }
        // 不足长度前面补0
        return String.format("%" + len + "s", binaryStr).replace(' ', '0');
    }

    public static StringBuffer bytesToBinaryLow(byte[] bArray, int digits) {
        StringBuffer outStr = new StringBuffer();
        int pos = 0;
        for (byte b : bArray) {
            //高四位
            pos = (b & 0xF0) >> 4;
            outStr.append(binaryArray[pos]);
            //低四位
            pos = b & 0x0F;
            outStr.append(binaryArray[pos]);
        }
        return new StringBuffer(outStr.substring(outStr.length()-digits, outStr.length()));
    }

    /**
     * 字节数组转ASCII字符串
     *
     * @param bytes
     * @return
     */
    public static String bytesToAsciiString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            sb.append((char) bytes[i]);
        }
        return sb.toString();
    }

    public static byte[] getMACAddr() {
        try {
            NetworkInterface netInterface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
            // 获得Mac地址的byte数组
            return netInterface.getHardwareAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static double formula(String formula, double x) {
        Expression expression = ExpressionTree.parse(formula);
        VarMap vm = new VarMap();
        FuncMap fmm = new FuncMap();
        fmm.loadDefaultFunctions();
        vm.setValue("x", x);
        return expression.eval(vm, fmm);
    }

    public static long bytesToLongNU(byte[] bytes) {
        if (bytes[0] >> 7 == 0) return ByteUtil.bytesToLong(bytes);
        else return ByteUtil.bytesToLongf(bytes);
    }

    /**
     * 遥测解扰 A9
     * @param bytes
     * @return
     */
    public static byte[] telemetryDescrambleA9(byte[] bytes){
        byte[] data = new byte[bytes.length];
        try {
            for( int i = 0 ; i < bytes.length ; i ++ ) {
                int c = bytes[i] ^ jrArrayA9[i % 255];
                data[i] = (byte) c;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 字节补加
     * @param bytes
     * @param repairByte
     * @param repairLength
     * @return
     */
    public static byte[] bytesRepairX(byte[] bytes, byte repairByte, int repairLength){
        if (repairLength <= 0) return bytes;
        byte[] repairBytes = new byte[repairLength];
        for (int i = 0; i < repairLength; i++) {
            repairBytes[i] = repairByte;
        }
        return byteMerger(bytes, repairBytes);
    }

    public static byte[] bytesRepairXLen(byte[] bytes, byte repairByte, int totalLength){
        if (totalLength == 0) return bytes;
        return bytesRepairX(bytes, repairByte, totalLength - (bytes==null?0:bytes.length));
    }


    /**
     * 字节插入
     * @param bytes 源数据
     * @param offset 插入位置
     * @param ins 插入数据
     * @return
     */
    public static byte[] bytesInsert(byte[] bytes, int offset, byte[] ins) {
        if (bytes == null) return null;
        if (ins == null) return bytes;
        if (offset < 0 || offset > bytes.length) return bytes;
        if (offset == 0){
            return byteMerger(ins, bytes);
        }
        if (offset == bytes.length){
            return byteMerger(bytes, ins);
        }
        return byteMergerAll(subBytes(bytes, 0, offset), ins, subBytes(bytes, offset));
    }

    public static byte[] bytesReplace(byte[] bytes, int offset, byte[] replace){
        if (replace == null) return bytes;
        if (offset + replace.length > bytes.length) return bytes;
        System.arraycopy(replace, 0, bytes, offset, replace.length);
        return bytes;
    }

    public static byte[] byteOrder(byte[] bytes){
        if (bytes == null || bytes.length == 0) return null;
        byte[] tmp = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            tmp[i] = bytes[bytes.length - i - 1];
        }
        return tmp;
    }

    public static List<byte[]> bytesToList(byte[] bytes, int itemLen){
        List<byte[]> list = new ArrayList<>();
        int loop = (bytes.length % itemLen) == 0 ? bytes.length / itemLen : bytes.length / itemLen + 1;
        for (int i = 0; i < loop; i++) {
            byte[] itemBytes = subBytes(bytes, i * itemLen, itemLen);
            if (itemBytes == null){
                itemBytes = subBytes(bytes, i * itemLen);
            }
            list.add(itemBytes);
        }
        return list;
    }


    public static byte[] aesEncrypt(byte[] content, String key) {
        try {
//            String aa[] = new String[]{"AES/CBC/NoPadding", "AES/ECB/NoPadding", "AES/OFB/NoPadding", "AES/PCBC/NoPadding"};
            SecretKeySpec skeySpec = new SecretKeySpec(hexToBytes(key), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            return cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] bytesBigLittleChange(byte[] bytes){
        byte[] newBytes = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            newBytes[i] = bytes[bytes.length - i - 1];
        }
        return newBytes;
    }

    /**
     * 16进制转2进制,不拆分字符串,直接换转,按长度高位补0
     * @param s 16进制数据
     * @return 转换后的2进制数据
     */
    public final static String Hex_to_BinaryFull(String s, int leng) {
        String str = FullBinary(Long.toBinaryString(Long.valueOf(s, 16)), leng);
        return str;
    }

    /**
     * 2进制数高位补0
     *
     * @param binary
     *            2进制数据
     * @param len
     *            所需2进制数据长度
     * @return 高位补0后的2进制数
     */
    public final static String FullBinary(String binary, int len) {
        if (binary.length() < len) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < len - binary.length(); i++) {
                sb.append("0");
            }
            return sb.append(binary).toString();
        } else {
            return binary;
        }
    }

    /**
     * 2进制转16进制
     *
     * @param s
     *            2进制数据
     * @return 转换后的16进制数据
     */
    public final static String Binary_to_Hex(String s) {
        if (s == null || s.equals("")) {
            return "0";
        }
        if (s.trim().substring(0, 1).equals("-")) {
            return "-"
                    + Long.toHexString(Long.valueOf(s.trim().substring(1), 2));
        } else {
            String rtn_hex = "";
            if (s.length() % 8 != 0) {
                s = FullBinary(s, s.length() + 8 - s.length() % 8);
            }
            while (s.length() > 0) {
                rtn_hex += Long.toHexString(Long.valueOf(s.substring(0, 4)
                        .trim(), 2));
                s = s.substring(4);
            }
            if (rtn_hex.length() % 2 == 1) {
                rtn_hex = "0" + rtn_hex;
            }
            return rtn_hex.toUpperCase();
        }
    }


    /**
     * 2进制转10进制
     *
     * @param s
     *            2进制数据
     * @return 转换后的10进制数据
     */
    public final static String Binary_to_Dec(String s) {
        if (s == null || s.equals("")) {
            return "0";
        }
//		while (s.substring(0, 1).equals("0") && s.length() > 1) {
//			s = s.substring(1);
//		}
        if (s.length() > 63) { // 数据过大，超过long最大范围
            return "0";
        }
        return Long.valueOf(s.trim(), 2) + "";
    }

    public static StringBuffer hexToBinary(String hex){
        return bytesToBinary(hexToBytes(hex));
    }

    public static Object functionInvoke(String functionName, String functionBody, Object... funParams){
        try {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
            engine.eval(functionBody);
            Invocable invoke = (Invocable) engine;
            return invoke.invokeFunction(functionName, funParams);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static Double checkFn(String fnBody,String param){
        if(fnBody.contains("function")){
            Object o = ByteUtil.functionInvoke(StrUtil.subBetween(fnBody,"function ","(").trim(), fnBody, Double.parseDouble(param));
            return Convert.toDouble(o);
        }
        return ByteUtil.formula(fnBody, Double.parseDouble(param));
    }

    public static byte[] bytesNegation(byte[] bytes){
        byte[] tmp = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            tmp[i] = (byte) ~bytes[i];
        }
        return tmp;
    }

    /**
     * 计算字节数组的按字节累加和模256取反加1的结果
     *
     * @param byteArray 输入的字节数组
     * @return 计算后的校验和
     */
    public static byte calculateChecksum(byte[] byteArray) {
        int sum = 0;

        // 按字节累加
        for (byte b : byteArray) {
            sum += b & 0xFF; // 将byte转换为正数（无符号）进行累加
        }

        // 模256取反加1
        byte checksum = (byte) ((~sum + 1) & 0xFF);

        return checksum;
    }


    public static void main(String[] args) {
        try {


        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
